home *** CD-ROM | disk | FTP | other *** search
/ Merciful 2 / Merciful - Disc 2.iso / software / d / dialupv3.06.lha / dialup / io.c < prev    next >
C/C++ Source or Header  |  1996-01-30  |  11KB  |  459 lines

  1. #include "dialup.h"
  2.  
  3. extern const UBYTE         *prgname;
  4. extern struct IOExtSer        *serialIOReq;
  5. extern struct timerequest    *timereq;
  6. extern BPTR            repfile;
  7. extern UBYTE            *rxbuffer;
  8. extern LONG            arg[];
  9.  
  10.  
  11.  
  12. BOOL    isend( UBYTE *send );    /* real send with \r, \n and \t remapping, string must be in a bigger buffer */
  13.  
  14. UBYTE *
  15. expectFromSer( UBYTE *expect, USHORT waittime )
  16. {
  17.     UBYTE *result = NULL;
  18.     ULONG WaitMask, timebit, serbit, wres;
  19.  
  20.     WaitMask = 0;
  21.  
  22.     if ( waittime )
  23.     {
  24.         if ( arg[A_VERBOSE] && !expect )
  25.             msg("waiting %ld seconds\n", expect, waittime);
  26.         timebit = 1L << timereq->tr_node.io_Message.mn_ReplyPort->mp_SigBit;
  27.         SetSignal(0L, timebit);
  28.         WaitMask |= SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_F | timebit;
  29.         timereq->tr_node.io_Command = TR_ADDREQUEST;
  30.         timereq->tr_time.tv_secs    = waittime;
  31.         timereq->tr_time.tv_micro    = 0;
  32.         SendIO((struct IORequest *)timereq);
  33.         if ( !expect )
  34.         {
  35.             while ( ! ( (wres = Wait(WaitMask)) & WaitMask ) )
  36.             ; /* Wait for the timeout, no string expected! */
  37.             if ( wres & timebit )
  38.             {
  39.                 *rxbuffer = '\0';
  40.                 result = rxbuffer;
  41.             };
  42.         };
  43.     };
  44.  
  45.     if ( expect )
  46.     {
  47.         UBYTE *wptrb;
  48.         UBYTE *repptr;
  49.  
  50.         UBYTE mbuf[MAXMATCHSTRING * 25];
  51.         UBYTE *msa[MAXMATCHSTRING];
  52.  
  53.         if ( strlen(expect) > sizeof(mbuf) )
  54.         {
  55.             msg("expectFromSer: expectstring to long!");
  56.             _FAIL_;
  57.         };
  58.  
  59.         if ( arg[A_VERBOSE] )
  60.             msg("expecting %s for %ld seconds\n", expect, waittime);
  61.  
  62.         buildMatchStringArray(expect, mbuf, msa);
  63.  
  64.         serbit =  1L << serialIOReq->IOSer.io_Message.mn_ReplyPort->mp_SigBit;
  65.         SetSignal(0L, serbit);
  66.         WaitMask |= SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_F | serbit;
  67.         wptrb = repptr = rxbuffer;
  68.         wres = 0;
  69.         do
  70.         {
  71.             UBYTE *spt;    
  72.  
  73.             serialIOReq->IOSer.io_Command  = SDCMD_QUERY;
  74.             DoIO((struct IORequest *)serialIOReq);
  75.             serialIOReq->IOSer.io_Command  = CMD_READ;
  76.             serialIOReq->IOSer.io_Data       = (APTR)wptrb;
  77.             /* while there are chars on the serial, set and get them (upto bufsize): */
  78.             if ( ( serialIOReq->IOSer.io_Length = min(serialIOReq->IOSer.io_Actual, RXBUFSIZE - (wptrb - rxbuffer)) ) > 0 )
  79.             {
  80.                 DoIO((struct IORequest *)serialIOReq);
  81.                 wptrb += serialIOReq->IOSer.io_Actual;
  82.                 continue;
  83.             }
  84.             *wptrb = '\0'; /* Terminate received string and replace any received \0's with spaces, to make a stringsearch possible: */
  85.             while ( spt = memchr(repptr, '\0', wptrb - repptr ) )
  86.                 memmove(spt, spt + 1, wptrb-- - spt);
  87.  
  88.             /* Report the conversation. The modem echos commands sent to it: */
  89.             if ( repfile && wptrb > repptr )
  90.             {
  91.                 Write( repfile, repptr, wptrb - repptr);
  92.                 repptr = wptrb;
  93.             };
  94.  
  95.                 /* check whether one of the matchstrings is in the receive buffer. Stop and return it if so. */
  96.             if ( result = matchString(rxbuffer, msa) )
  97.                 break;
  98.  
  99.                 /* wait for one char, break or timeout: */
  100.             serialIOReq->IOSer.io_Length = 1;
  101.             SetSignal(0L, serbit);
  102.             SendIO((struct IORequest *)serialIOReq);
  103.             while ( ! ( (wres = Wait(WaitMask)) & WaitMask ) )
  104.             ;
  105.             if ( wres & serbit || wres & SIGBREAKF_CTRL_F )
  106.             {
  107.                 if(CheckIO((struct IORequest *)serialIOReq) )    /* If request is complete... */
  108.                 {
  109.                     WaitIO((struct IORequest *)serialIOReq);    /* clean up and remove reply */
  110.                     wptrb += serialIOReq->IOSer.io_Actual;
  111.                     *wptrb = '\0';                                /* Terminate received string */
  112.                 }
  113.             }
  114.             else if ( (wres & timebit) )
  115.             {
  116.                 UBYTE *cbptr;
  117.                 UBYTE *rbptr;
  118.                 UBYTE ccnt;
  119.                 for(rbptr = rxbuffer, cbptr = wptrb + 1; ( rbptr < wptrb ) && ((cbptr + 20) < (rxbuffer + RXBUFSIZE)); rbptr += 8)
  120.                 {
  121.                     cbptr += sprintf(cbptr, "%08lX %08lX  ", *(ULONG *)rbptr, *(ULONG *)(rbptr + 4) );
  122.                     for(ccnt = 0; rbptr[ccnt] && ccnt < 8; ccnt++)
  123.                         if ( strchr("\n\r\t", rbptr[ccnt] ) )
  124.                             rbptr[ccnt] = 1;
  125.                         cbptr += sprintf(cbptr, "%-.4s ", rbptr);
  126.                         if (rbptr + 4 < wptrb)
  127.                             cbptr += sprintf(cbptr, "%-.4s\n", rbptr + 4 );
  128.                 };
  129.                 msg("TIMEOUT, after waiting %ld secs for:\n'%s'\nReceived:\n%s", waittime, expect, wptrb + 1);
  130.             }
  131.         }
  132.         while ( ! ( wres & ( SIGBREAKF_CTRL_C | timebit ) ) )
  133.         ;
  134.  
  135.         if ( wres & SIGBREAKF_CTRL_C )
  136.         {
  137.             strcpy(wptrb, BREAKSTR);
  138.             wptrb += sizeof(BREAKSTR);
  139.         };
  140.  
  141.         if( !CheckIO((struct IORequest *)serialIOReq) ) /* If request is complete... */
  142.         {
  143.             AbortIO((struct IORequest *)serialIOReq);  /* Ask device to abort request, if pending */
  144.             WaitIO((struct IORequest *)serialIOReq);   /* clean up and remove reply */
  145.             if ( SetSignal(0, 0) & serbit )
  146.                 SetSignal(0, serbit );
  147.         }
  148.  
  149.         if ( repfile && (wptrb > repptr) )
  150.         {
  151.             Write( repfile, repptr, wptrb - repptr); /* Report the conversation, cause normaly modem echos commands sent to it. */
  152.             repptr = wptrb;
  153.         };
  154.     };
  155.  
  156.     if( waittime && !CheckIO((struct IORequest *)timereq) ) /* Abort any pending timer requests */
  157.     {
  158.         AbortIO((struct IORequest *)timereq);
  159.         WaitIO((struct IORequest *)timereq);
  160.         if ( SetSignal(0, 0) & timebit )
  161.             SetSignal(0, timebit );
  162.     }
  163.     return( result );
  164. }
  165.  
  166.  
  167.  
  168. #define SCRATCHBUFSIZE 1000
  169.  
  170.  
  171.  
  172. BOOL
  173. sendLine( UBYTE *send )
  174. {
  175.     UBYTE buf[SCRATCHBUFSIZE];
  176.  
  177.     if ( strlen(send) >= SCRATCHBUFSIZE - 1 )
  178.         _FAIL_
  179.     sprintf(buf, "%s\r", send);
  180.     return(isend(buf));
  181. }
  182.  
  183.  
  184.  
  185. UBYTE *
  186. sendEx( UBYTE *send , UBYTE *expect, USHORT waittime )
  187. {
  188.     UBYTE buf[SCRATCHBUFSIZE];
  189.  
  190.     if ( strlen(send) >= SCRATCHBUFSIZE - 1 )
  191.         _FAIL_
  192.     sprintf(buf, "%s\r", send);
  193.     if ( !isend(buf) )
  194.         return(FALSE);
  195.     return( expectFromSer(expect, waittime) );
  196. }
  197.  
  198.  
  199.  
  200. UBYTE *
  201. exSend( UBYTE *expect, USHORT waittime, UBYTE *send )
  202. {
  203.     UBYTE *rxbufp;
  204.  
  205.     if ( strlen(send) >= SCRATCHBUFSIZE - 1 )
  206.         _FAIL_
  207.     if (rxbufp = expectFromSer(expect, waittime) )
  208.     {
  209.         UBYTE buf[SCRATCHBUFSIZE];
  210.         sprintf(buf, "%s\r", send);
  211.         if ( !isend(buf) )
  212.             return(NULL);
  213.     }
  214.     return(rxbufp);
  215. }
  216.  
  217.  
  218.  
  219. BOOL
  220. sendToSer( UBYTE *send )
  221. {
  222.     UBYTE buf[SCRATCHBUFSIZE];
  223.  
  224.     if ( strlen(send) >= SCRATCHBUFSIZE )
  225.         _FAIL_
  226.     strcpy(buf, send);    /* copying string to be able modify it */
  227.     return(isend(send));
  228. }
  229.  
  230.  
  231. BOOL
  232. isend( UBYTE *send )    /* this gets only called by sendEx(), exSend() and sendToSer() */
  233. {
  234.     UBYTE *mptr = send;
  235.  
  236.     while ( *mptr != '\0' )
  237.     {
  238.         if ( *mptr++ == '\\' )
  239.         {
  240.                     if ( *mptr == 'r' )
  241.                  *mptr = '\r'; /* overwrite it insitu */
  242.             else if ( *mptr == 'n' )
  243.                  *mptr = '\n'; /* ditto */
  244.             else if ( *mptr == 't' )
  245.                  *mptr = '\t'; /* ditto */
  246.         /* then get rid of the '\\' by left shifting the string */
  247.             memmove(mptr - 1, mptr, strlen(mptr) + 1);
  248.         };
  249.     };
  250.  
  251.     if ( arg[A_VERBOSE] )
  252.         msg("Sending %s\n", send);
  253.  
  254.     Delay(2);
  255.     serialIOReq->IOSer.io_Command  = CMD_WRITE;
  256.     serialIOReq->IOSer.io_Data       = (APTR)send;
  257.     serialIOReq->IOSer.io_Length   = strlen(send);
  258.     if ( DoIO( (struct IORequest *)serialIOReq ) )
  259.     {
  260.         msg("failed to write to serial line\n");
  261.         return(FALSE);
  262.     }
  263.     return(TRUE);
  264. }
  265.  
  266.  
  267. /* new function to handle WAKEUPSTRING -GH- */
  268. BOOL
  269. sendWUSSer( UBYTE *send )
  270. {
  271.     UBYTE buf[SCRATCHBUFSIZE];
  272.  
  273.     if ( strlen(send) >= SCRATCHBUFSIZE )
  274.         _FAIL_
  275.     strcpy(buf, send);    /* copying string to be able modify it */
  276.     return(wuSend(send));
  277. }
  278.  
  279.  
  280. BOOL
  281. wuSend( UBYTE *send )    /* this gets only called by sendWUSSer() -GH- */
  282. {
  283.     UBYTE *mptr = send;
  284.         UBYTE kick;
  285.  
  286.     while ( *mptr != '\0' )
  287.     {
  288.         if ( *mptr++ == '\\' )
  289.         { /* added to implement a delay mechanism by Gene Heskett */
  290.                     if ( *mptr == '*' )
  291.                         Delay(15); /* 1/4 second delay */
  292.                     else if ( *mptr == 'r' )
  293.             {
  294.                         kick = '\r';
  295.                         kickport (& kick );
  296.                     }
  297.             else if ( *mptr == 'n' )
  298.                     {
  299.                         kick = '\n';
  300.                         kickport ( & kick );
  301.                     }
  302.             else if ( *mptr == 't' )
  303.                     {
  304.                         kick = '\t';
  305.                         kickport ( & kick );
  306.                     }
  307.             memmove(mptr - 1, mptr, strlen(mptr) + 1);
  308.         };
  309.     };
  310.         return TRUE;
  311. } /* this is the new end of this routine -GH- */
  312.  
  313.  
  314. BOOL
  315. kickport ( UBYTE *send ) /* called *only* by wuSend */
  316. {
  317.     if ( arg[A_VERBOSE] )
  318.         msg("Sending %s\n", send);
  319.  
  320.     serialIOReq->IOSer.io_Command   = CMD_WRITE;
  321.     serialIOReq->IOSer.io_Data    = (APTR)send;
  322.     serialIOReq->IOSer.io_Length    = 1;
  323.     if ( DoIO( (struct IORequest *)serialIOReq ) )
  324.     {
  325.         msg("failed to write to serial line\n");
  326.         return(FALSE);
  327.     }
  328.     return(TRUE);
  329. }
  330.  
  331.  
  332. /*
  333. ** The next lines are stolen from the slip.device (Rhialto Seibert, Comodore)
  334. **
  335. ** ReadConfig
  336. **
  337. ** Attempt to read in and parse the driver's configuration file.
  338. **
  339. ** The files are named by ENV:SANA2/slip0.config where X is the decimal
  340. ** representation of the device's unit number.
  341. **
  342. */
  343.  
  344. #define LINEBUFFSIZE 1024
  345. #define NUMARGS 10
  346.  
  347. BOOL ReadConfig(STRPTR sanacfgfile, USHORT sanaUnit, struct SP *sp)
  348. {
  349.     UBYTE *linebuff;
  350.     UBYTE buff[80] = "ENV:SANA2/";
  351.     UBYTE *termchar;
  352.     struct RDArgs *rdargs;
  353.     BPTR ConfigFile;
  354.     LONG arg[NUMARGS];
  355.     BOOL status = FALSE;
  356.     ULONG linenum=0;
  357.     UWORD i;
  358.  
  359.     sprintf(buff + ( strchr(sanacfgfile, ':') ? 0 : strlen(buff) ), sanacfgfile, (ULONG)sanaUnit);
  360.     if(ConfigFile = Open(buff,MODE_OLDFILE))
  361.     {
  362.         if(linebuff = AllocMem(LINEBUFFSIZE, MEMF_CLEAR|MEMF_PUBLIC))
  363.         {
  364.             if(rdargs = AllocDosObject(DOS_RDARGS, NULL))
  365.             {
  366.                 while( FGets( ConfigFile, linebuff, LINEBUFFSIZE - 1) )
  367.                 {
  368.                     linenum++;
  369.                     if(linebuff[0] == '#') /* Skip comment lines */
  370.                         continue;
  371.  
  372.                     rdargs->RDA_Source.CS_Buffer = linebuff;
  373.                     rdargs->RDA_Source.CS_Length = LINEBUFFSIZE;
  374.                     rdargs->RDA_Source.CS_CurChr = 0;
  375.  
  376.                     /* ReadArgs() requires that the line be null-terminated or funny things happen. */
  377.                     termchar = (UBYTE *) linebuff + strlen(linebuff);
  378.                     *termchar = '\n';
  379.                     termchar++;
  380.                     *termchar = 0;
  381.  
  382.                     for(i = 0; i < NUMARGS ; i++)
  383.                         arg[i] = NULL;
  384.                     if( ReadArgs( "SERNAME/A,SERUNIT/A/N,SERBAUD/A/N,IPSTR/A,CD=CARRIERDETECT/S,7WIRE/S,EOFMODE/S,MTU/K/N,THEREST/F", arg, rdargs ) )
  385.                     {
  386.                         status = TRUE;
  387.                         strcpy( sp->serDevName,    (UBYTE *)arg[0] );
  388.                         sp->serUnit            = *((ULONG *)arg[1]);
  389.                         sp->serBaudRate        = *((ULONG *)arg[2]);
  390.                         sp->listen2CD        =             arg[4] ? TRUE : FALSE;
  391.                         sp->serHWHS            =             arg[5] ? TRUE : FALSE;
  392.                         FreeArgs(rdargs);
  393.                         break;
  394.                     }
  395.                     else
  396.                     {
  397.                         msg("Error parsing sana arguments in %s", buff);
  398.                         break;
  399.                     }
  400.                 }
  401.                 FreeDosObject(DOS_RDARGS, rdargs);
  402.             }
  403.             FreeMem(linebuff, LINEBUFFSIZE);
  404.         }
  405.         Close(ConfigFile);
  406.     }
  407.     return(status);
  408. }
  409.  
  410.  
  411.  
  412. VOID
  413. msg(UBYTE *msg, ...)
  414. {
  415.     extern BPTR    mystderr;
  416.     va_list args;
  417.  
  418.     va_start(args, msg);
  419.      if(mystderr)
  420.     {
  421.         VFPrintf(mystderr, msg, args);
  422.         VFPrintf(mystderr, "\n", NULL);
  423.     }
  424.     else
  425.     {
  426.         struct Library *IntuitionBase;
  427.         static struct EasyStruct es;
  428.  
  429.         if(IntuitionBase = OpenLibrary("intuition.library", 37))
  430.         {
  431.             es.es_StructSize=sizeof(struct EasyStruct);
  432.             es.es_Flags = 0;
  433.             es.es_Title = prgname;
  434.             es.es_TextFormat = msg;
  435.             es.es_GadgetFormat = "OK";
  436.             EasyRequestArgs(NULL, &es, 0, args);
  437.             CloseLibrary(IntuitionBase);
  438.         };
  439.     }; 
  440.     va_end(args);
  441. }
  442.  
  443.  
  444.  
  445. BOOL
  446. carrier()
  447. {
  448.     /* modem online? */
  449.  
  450.     if (!serialIOReq)
  451.         return(FALSE);
  452.  
  453.     serialIOReq->IOSer.io_Command  = SDCMD_QUERY;
  454.     if ( DoIO((struct IORequest *)serialIOReq) )
  455.         msg("Error: Query serial line.");
  456.     return( (BOOL)( (serialIOReq->io_Status & ( 1 << 5 ) ) == 0 ) );
  457. }
  458.  
  459.